#include "look.h"
#include "ui_look.h"

#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>

#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QVideoWidget>
#include <QFileDialog>
#include <QTime>
#include <QThread>
#include <QTimer>
#include <QMessageBox>

#include <QNetworkReply>
#include <QNetworkRequest>
#include <QListWidgetItem>
#include "common/logininfoinstance.h"
#include "selfwidget/filepropertyinfo.h"
#include "common/downloadtask.h"
#include <QHttpMultiPart>
#include <QHttpPart>

#include <QApplication>

look::look(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::look)
{

    // http管理类对象
    m_manager1 = Common::getNetManager();

    ui->setupUi(this);

    ui->playList->setContextMenuPolicy(Qt::CustomContextMenu);

    //m_statusBar = new QStatusBar(this);
   // layout()->addWidget(m_statusBar);

    //contenxMenu = new QMenu(this);
    //layout()->addWidget(contenxMenu);

    contenxMenu = new QMenu(this);
    contenxMenu->addAction("删除...", this, [this](){
        int pos = ui->playList->currentRow();
        QString name = m_nameList.value(pos);
        m_nameList.removeAt(pos);
        m_ulrMap.remove(name);
        m_mediaPlayList->removeMedia(pos);
        ui->playList->takeItem(pos);
        savePlayList();
    });

    contenxMenu->addAction("清空列表...", this, [this](){
        m_nameList.clear();
        m_ulrMap.clear();
        m_mediaPlayList->clear();
        ui->playList->clear();
        savePlayList();
    });

    QVideoWidget* videoWidget = new QVideoWidget(this); //设置视频输出到窗口
    ui->playWidgetLayout->addWidget(videoWidget);

    m_mediaPlayer = new QMediaPlayer(this);
    m_mediaPlayer->setVideoOutput(videoWidget);

    m_mediaPlayList = new QMediaPlaylist(this);
    m_mediaPlayer->setPlaylist(m_mediaPlayList);

    connect(m_mediaPlayer, &QMediaPlayer::stateChanged, this, [this](QMediaPlayer::State newState) {
        if (newState == QMediaPlayer::PlayingState) //设置播放按钮的 开始、暂停
        {
            updatePlayText(false);
        }
        else
        {
            updatePlayText(true);
        }
    });

    connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, [this](qint64 position) {
        ui->playPosSlider->setValue(position);  //设置进度条
        updateDiplayPosInfo();
    });

    connect(m_mediaPlayer, &QMediaPlayer::durationChanged, this, [this](qint64 duration) {
        ui->playPosSlider->setMaximum(duration);
        ui->playPosSlider->setValue(0);
    });

    connect(m_mediaPlayer, (void (QMediaPlayer::*)(QMediaPlayer::Error))&QMediaPlayer::error, this, [this](QMediaPlayer::Error error) {
        Q_UNUSED(error)
        //ui->statusbar->showMessage(m_mediaPlayer->errorString());
        QMessageBox::information(this, "这是啥", "我不认识");
    });

    updatePlayText(true);
    loadPlayList();
}

look::~look()
{
    delete ui;
}

void look::updatePlayText(bool play)
{
    ui->playOrPauseButton->setText(play ? "播放" : "暂停");
}

void look::updateDiplayPosInfo()
{
    auto convertDispalyStr = [](int totalMilliseconds) -> QString {
        QTime tm = QTime(0, 0, 0, 0).addMSecs(totalMilliseconds);
        return  tm.toString("hh:mm:ss");
    };
    const QString position = convertDispalyStr(ui->playPosSlider->value());
    const QString duration = convertDispalyStr(ui->playPosSlider->maximum());
    ui->playPosLable->setText(QString("%1 / %2").arg(position).arg(duration));
}

void look::loadPlayList()
{
    QFile file("./conf/huancun.json");

    if (!file.exists())
    {
        QMessageBox::information(this, "错误！", "不存在配置文件?建新");

        file.setFileName("./conf/huancun.json");
        file.open(QIODevice::ReadWrite|QIODevice::Text);
       // ui->statusbar->showMessage("不存在配置文件...");
        file.close();
        //return ;
    }
    if (!file.open(QFile::ReadOnly))
    {
        QMessageBox::information(this, "错误！", "打开配置文件用于加载失败...");
        //ui->statusbar->showMessage("打开配置文件用于加载失败...");
        return ;
    }
    QJsonArray jsonArray = QJsonDocument::fromJson(file.readAll()).array();
    for (QJsonValue value : jsonArray)
    {
        QJsonObject jsonObject = value.toObject();
        QString name = jsonObject.value("name").toString();
        QString url = jsonObject.value("url").toString();
        m_nameList.append(name);
        m_ulrMap[name] = url;
        m_mediaPlayList->addMedia(QMediaContent(url));
    }
    ui->playList->addItems(m_nameList);
    file.close();

}

void look::savePlayList()
{
    QJsonArray jsonArray;
    for (QString name : m_nameList)
    {
        QJsonObject jsonObject;
        jsonObject["name"] = name;
        jsonObject["url"] = m_ulrMap.value(name);
        jsonArray.append(jsonObject);
    }
    QDir dir("./conf");
    if (!dir.exists())
    {
        dir.mkpath(dir.absolutePath());
    }
    QFile file(dir.filePath("huancun.json"));
    if (!file.open(QFile::WriteOnly))
    {
        //ui->statusbar->showMessage("打开配置文件用于存储失败...");
        QMessageBox::information(this, "错误！", "打开配置文件用于存储失败...");
        return ;
    }
    file.write(QJsonDocument(jsonArray).toJson());
    file.close();

}



void look::on_actionOpenLocalFile_clicked() //打开本地文件
{
    QString path = QFileDialog::getOpenFileName();
    QFileInfo fileInfo(path);
    QString url = QUrl::fromLocalFile(fileInfo.absoluteFilePath()).toString();
    QString fileName = fileInfo.fileName();

    ui->playList->addItem(fileName);
    m_mediaPlayList->addMedia(QMediaContent(url));

    QTimer::singleShot(800, this, [this](){
        m_mediaPlayer->play();

    });

    m_nameList.append(fileName);
    m_ulrMap[fileName] = url;
    savePlayList();
}

void look::on_actionAddURL_clicked() //添加网络文件的url
{
    getmediafromsql();//获取十个新媒体 加入缓存链表中

    while(addmediahash()); //从缓存链表中全部取走并添加medialist，
    m_index = 0;
    if(m_size < m_index)
        QMessageBox::information(this, "看完了", "看完了！！！！");
    on_nextButton_clicked();
}

void look::getmediafromsql() //发送post请求size个新媒体
{
    QNetworkRequest request1; //请求对象

    LoginInfoInstance *login = LoginInfoInstance::getInstance(); //获取单例

    QString url;
    QString tmp = "all";
    url = QString("http://%1:%2/myfiles?cmd=%3").arg(login->getIp()).arg(login->getPort()).arg(tmp);
    request1.setUrl(QUrl( url )); //设置url
    cout << "myfiles url: " << url;

    //qt默认的请求头
    //request.setRawHeader("Content-Type","text/html");
    request1.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");

    /*
    {
        "user": "yoyo"
        "token": "xxxx"
        "start": 0
        "count": size
    }
    */
    QByteArray data1 = setFilesListJson( login->getUser(), login->getToken(), m_start, m_count);
    //改变文件起点位置
    m_start += m_count;

    //发送post请求
    QNetworkReply * reply1= m_manager1->post( request1, data1 ); //m_manager1要初始化
    qDebug() << "发送了一个请求";
    if(reply1 == NULL)
    {
        cout << "reply == NULL";
        return;
    }

    //获取请求的数据完成时，就会发送信号SIGNAL(finished())
    connect(reply1, &QNetworkReply::finished, [=]()
    {
        if ( reply1->error() != QNetworkReply::NoError) //有错误
        {
            cout << reply1->errorString();
            reply1->deleteLater(); //释放资源
            return;
        }

        //服务器返回用户的数据
        QByteArray array = reply1->readAll();
        cout << "file info:" << array;

        reply1->deleteLater();

        //token验证失败
        if("111" == m_cm.getCode(array) ) //common.h
        {
            QMessageBox::warning(this, "账户异常", "请重新登陆！！！");
            return; //中断
        }

        //不是错误码就处理文件列表json信息
        if("015" != m_cm.getCode(array) ) //common.h
        {
            //cout << array.data();
            getFileJsonInfo(array);//解析文件列表json信息，存放在文件列表中
        }

    });
}

bool look::addmediahash() //给QMediaPlaylist添加新媒体
{
    if(!m_lookList.empty())
    {
        auto it = m_lookList.begin();
        QString displayName = (*it)->filename;
        QString url = (*it)->url;

        ui->playList->addItem(displayName);
        m_mediaPlayList->addMedia(QMediaContent(url));

        QTimer::singleShot(800, this, [this](){
            m_mediaPlayer->play();
        });

        m_nameList.append(displayName);
        m_ulrMap[displayName] = url;
        savePlayList();
        m_lookList.erase(it);

        return true;
    }
    return false;
}

// 设置json包
QByteArray look::setFilesListJson(QString user, QString token, int start, int count)
{
    /*{
        "user": "yoyo"
        "token": "xxx"
        "start": 0
        "count": 10
    }*/
    QMap<QString, QVariant> tmp;
    tmp.insert("user", user);
    tmp.insert("token", token);
    tmp.insert("start", start);
    tmp.insert("count", count);

    QJsonDocument jsonDocument = QJsonDocument::fromVariant(tmp);
    if ( jsonDocument.isNull() )
    {
        cout << " jsonDocument.isNull() ";
        return "";
    }

    cout << jsonDocument.toJson().data();

    return jsonDocument.toJson();
}

//解析json包
void look::getFileJsonInfo(QByteArray data)
{
    QJsonParseError error;

    /*
    {
    "user": "yoyo",
    "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
    "time": "2017-02-26 21:35:25",
    "filename": "test.mp4",
    "pv": 0,
    "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
    "size": 27473666,
     "type": "mp4"
    }
    */
    //-- user	文件所属用户
    //-- md5 文件md5
    //-- createtime 文件创建时间
    //-- filename 文件名字
    //-- pv 文件下载量，默认值为0，下载一次加1
    //-- url 文件url
    //-- size 文件大小, 以字节为单位
    //-- type 文件类型： png, zip, mp4……

    //将来源数据json转化为JsonDocument
    //由QByteArray对象构造一个QJsonDocument对象，用于我们的读写操作
    QJsonDocument doc = QJsonDocument::fromJson(data, &error);
    if (error.error == QJsonParseError::NoError) //没有出错
    {
        if (doc.isNull() || doc.isEmpty())
        {
            cout << "doc.isNull() || doc.isEmpty()";
            return;
        }

        if( doc.isObject())
        {
            //QJsonObject json对象，描述json数据中{}括起来部分
            QJsonObject obj = doc.object();//取得最外层这个大对象

            QJsonArray array = obj.value("files").toArray();//用json数组保存的文件信息
            int size = array.size();   //数组个数
            cout << "size = " << size;

            m_size += size;

            for(int i = 0; i < size; ++i)
            {
                QJsonObject tmp = array[i].toObject(); //取第i个对象
                /*
                    //文件信息
                    struct FileInfo
                    {
                        QString md5;        //文件md5码
                        QString filename;   //文件名字
                        QString user;       //用户
                        QString time;       //上传时间
                        QString url;        //url
                        QString type;       //文件类型
                        qint64 size;        //文件大小
                        int pv;             //下载量
                        QListWidgetItem *item; //list widget 的item
                    };

                    {
                    "user": "yoyo",
                    "md5": "e8ea6031b779ac26c319ddf949ad9d8d",
                    "time": "2017-02-26 21:35:25",
                    "filename": "test.mp4",
                    "pv": 0,
                    "url": "http://192.168.31.109:80/group1/M00/00/00/wKgfbViy2Z2AJ-FTAaM3As-g3Z0782.mp4",
                    "size": 27473666,
                     "type": "mp4"
                    }
                */
                FileInfo *info = new FileInfo;
                info->user = tmp.value("user").toString(); //用户
                info->md5 = tmp.value("md5").toString(); //文件md5
                info->time = tmp.value("time").toString(); //上传时间
                info->filename = tmp.value("filename").toString(); //文件名字
                info->pv = tmp.value("pv").toInt(); //下载量
                info->url = tmp.value("url").toString(); //url
                info->size = tmp.value("size").toInt(); //文件大小，以字节为单位
                info->type = tmp.value("type").toString();//文件后缀
                QString type = info->type + ".png";
                info->item = new QListWidgetItem(QIcon( m_cm.getFileType(type) ), info->filename);

                //list添加节点
                m_lookList.append(info);
            }
        }
    }
    else
    {
        cout << "err = " << error.errorString();
    }

}

void look::on_playList_doubleClicked(const QModelIndex &index)
{
    if (!index.isValid())
    {
        return ;
    }
    QString name = ui->playList->item(index.row())->text();
    if (!m_ulrMap.contains(name))
    {
        //ui->statusbar->showMessage("播放失败，没有对应的ulr地址");
        if (QMessageBox::warning(this, "警告", "当前影视不能播放，是否删除", "是", "否") == 0)
        {
            m_nameList.removeAll(name);
            m_ulrMap.remove(name);
            ui->playList->takeItem(index.row());
            savePlayList();
        }
        return ;
    }
    m_mediaPlayList->setCurrentIndex(index.row());

    QTimer::singleShot(800, this, [this](){
        m_mediaPlayer->play();
    });

}

void look::on_playOrPauseButton_clicked()
{
    if (m_mediaPlayer->state() != QMediaPlayer::PlayingState)
    {
        m_mediaPlayer->play();
    }
    else
    {
        m_mediaPlayer->pause();
    }

}

void look::on_stopButton_clicked()
{
    m_mediaPlayer->stop();
}

void look::on_playPosSlider_sliderPressed()
{
    m_mediaPlayer->pause();
}

void look::on_playPosSlider_sliderReleased()
{
    m_mediaPlayer->play();
}

void look::on_playPosSlider_sliderMoved(int position)
{
    m_mediaPlayer->setPosition(position);
}

void look::on_playList_customContextMenuRequested(const QPoint &pos)
{
    contenxMenu->exec(ui->playList->mapToGlobal(pos));
}

void look::on_nextButton_clicked()
{
    m_mediaPlayList->next();
    m_index++;

    if(m_size - m_index < 2)
    {
        int size = m_size;
        getmediafromsql();//获取size个新媒体
        if(size != m_size)
        while(addmediahash()); //循环添加
        else
        {
            cout << "数据库无数据";
            if(m_index > m_size)
                QMessageBox::information(this, "看完了！！","看完了！！");
        }
    }
}
